热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

神经元|力点_CS231n笔记5WeightsUpdate与Dropout

篇首语:本文由编程笔记#小编为大家整理,主要介绍了CS231n笔记5--WeightsUpdate与Dropout相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了CS231n笔记5--Weights Update 与 Dropout相关的知识,希望对你有一定的参考价值。



Weights Update 与 Dropout

  • Weights Update 与 Dropout
    • 参数更新Weights Update
      • 学习率是怎么来的
      • 随机梯度下降-Stochastic Gradient Descent
      • Batch与SGD的合体Mini-Batch Gradient Descent
      • 再给力点Momentum来了
      • 考虑得再多一些-Nesterov Momentum Update
      • 平衡梯度的更新策略-AdaGrad
      • 尽量保持梯度的RMSProp方法
      • AdaDelta
      • 结合Momentum与AdaGradAdam Update
      • 逃不了的学习率
    • 正则化方法Dropout
    • 后言




参数更新:Weights Update



在进一步学习之前,先看看我们将要覆盖的权重更新方法的效果,图片来源:http://cs231n.github.io/neural-networks-3/



学习率是怎么来的

相信有机器学习基础的读者都很熟悉一个式子:

W=λdW
,这里的

λ
就是学习率,那么这个式子是怎么来的呢?(小编不敢在众大神面前班门弄斧,只是跟大家分享下,如果有什么改进,还望提出哦,谢谢!)
在传统的机器学习方法中,我们所遇到的一般都是凸问题(可以想象这种问题的Loss Function就想一个大锅,存在最小值),因此如果我们想要达到最小的Loss,我们就需要沿着这个函数的梯度方向往下走(即梯度下降),那么梯度方向就是

dW|dW|
,走的步长就是常数

Δ
,这时就会发现,如果用

W=ΔdW|dW|
在梯度较大的时候,也就是比较最优解的时候,W的更新有点太不紧不慢了,然而到了梯度较小的时候,也就是较靠近最优解的时候,W的更新竟然也保持着跟原来一样的速率,这样会导致W很容易更新过度反而远离了最优解。所以这时候就想了,既然在远离最优解的时候梯度大,在靠近最优解的时候梯度小,为何不干脆把这个性质利用起来呢?于是我我们就用

λ|W|
来代替

Δ
,最后得到了我们熟悉的式子

W=Wλ|W|dW|dW|=WλdW
。所以说这时的

λ
其实是具备了一些动态更新的特点的,别看它是个常数,但是显然,我们这里不是跟大家说这样就足够了,我们还可以权重得更好。也就是我下面要跟大家一起分享的其他几个Weights Update的方法。


随机梯度下降-Stochastic Gradient Descent

这种方法简称SGD(打这个名字好累,下面都用简称了= =)。SGD其实很简单,就是相比我们之前见到的Batch Gradient Descent方法使用全部数据做一轮迭代,SGD一轮迭代只用一条随机的数据,因此SGD的迭代次数会比BGD大很多,然而总体还是比BGD快。下面简单分析下SGD的优缺点。
优点:


  • 收敛速度快(通过减少总体的迭代次数)
  • 可以很快的见到效果

缺点:


  • 收敛时浮动,不稳定
  • 在最优解附近跳动,难以判断是否已经收敛
  • 随机访问可能造成巨大的IO开销



Batch与SGD的合体?Mini-Batch Gradient Descent!

看到SGD的优缺点,我们不禁想,有没什么办法可以即保留绝大部分的优点,同时有大幅的减弱缺点呢?答案是肯定的!就是我们这里介绍的Mini-Batch Gradient Descent。道理也很简单,就是SGD太极端了,一次一条,为何不一次五十条呢?是的,这个方法就是用一次迭代多条数据的方法。并且如果Batch Size选择合理,不仅收敛速度比SGD更快,更稳定,而且在最优解附近的跳动也不会很大,甚至能够得到比Batch Gradient Descent 更好的解。这样就综合了SGD和Batch Gradient Descent 的优点,同时弱化了缺点。总之不用多想,Mini-Batch比SGD和Batch Gradient Descent都好。


再给力点?Momentum来了

上面两种都是随机的方法,因此都存在不同程度的震荡,因此,如果能够以之前下降的方向作为参考,那么将会有利于下一次下降的方向(这个是成立的,因为下降的方向的期望是指向最优解)。下面给出Momentum Update的python代码:

v = momentum*v-learning_rate*dW
W += v

这里的v通常被称为第一moment。v可以初始化为0,momentum一般取0.5或0.9或0.99。从代码可以看出,在训练过程中,v不断积累和更新下降的速率和方向。从本节开头的动图也可以看出,Momentum的确比SGD快多了,但是由于有历史的影响,Momentum会出现越过最优解的情况,但是总体还是比单纯的随机方法快很多。


考虑得再多一些-Nesterov Momentum Update

NAG(Nesterov Accelerated Gradient)不仅仅把SGD梯度下降以前的方向考虑,还将Momentum梯度变化的幅度也考虑了进来。下面给出python的代码

v_prev = v
v = momentum*v-learning_rate*dx
x+=v+momentum*(v-v_prev)

从代码也可以看出,NAG多观察了Momentum拐弯的角度,因此,当Momentum在越过最优解的时候,Momentum会尽可能的希望拐回正轨,这时候NAG就会留意到Momentum在拐弯从而加速自己走回正轨的,所以我们看到动图中,NAG偏离最优解的程度更小些。



平衡梯度的更新策略-AdaGrad

在传统机器学习中,一种加速迭代速度的方法就是将数值归一化到一个一原点为中心的空间内,因为这样可以避免梯度在某些维度上跨度很小而拖慢迭代速度。而对于随机的方法,这种数值不同维度上的域的范围如果有很大的区别可能会导致非常糟糕的情况。试想一个二维的W,如果Loss Function对第二维的变化非常敏感,那么当随机方法在执行时,很有可能会在第二维处迈出了相对来说很大的一步,而在第一微处迈出了很小的一步,那么收敛效果就会不好。AdaGrad就是考虑到这种情况。AdaGrad通过不断积累每次随机梯度不同维度的大小,使得之后的梯度在该小的维度上小,该大的维度上大。下面给出AdaGrad的python代码

cache += dx**2
x+=-learning_rate*dx/(np.sqrt(cache)+1e-7)

这里的cache也常被称为第二moment。


尽量保持梯度的RMSProp方法

细心的读者可能会留意到,AdaGrad每次迭代都累加了梯度,这会导致在迭代后期,AdaGrad的梯度会变得很小,从而减慢了速度,RMSProp是Hinton在Coursera公开课上提出的方法,它尽可能的保持学习率不会下降得太快,下面给出python代码

cache = decay_rate*cache+(1-decay_rate)*dx**2
x+=-learning_rate*dx/(np.sqrt(cache)+1e-7)

这里的decay_rate一般取0.9或0.99


AdaDelta

相信大家一定也很好奇动图中那个飞得最好的AdaDelta是什么方法吧,然而课上并没有提到,于是小编就去谷歌了下,下面给出参考链接:



可能要教育网或者有数据库账号才能看吧….
http://arxiv.org/pdf/1212.5701.pdf


下面给出Python代码

cache_dx = delta*cache_dx + (1-delta)*(dx**2)
v = -learning_rate*np.sqrt(cache_x)*dx/(np.sqrt(cache_dx)+1e-7)
x += v
cache_x = delta*cache_x + (1-delta)*(v**2)



结合Momentum与AdaGrad:Adam Update

Momentum方法和AdaGrad方法都在解决权重更新不同的问题上有很大的作用,那么现在就将这两者合并起来,形成一个更加强大的方法,Adam。由于是两者的结合,那么我就不加赘述了,直接上代码

m = beta1*m+(1-beta1)*dx # update first moment
v = beta2*v+(1-beta2)*(dx**2) # update second moment
mb = m/(1-beta1**t) # correct bias
vb = v/(1-beta2**t) # correct bias
x+= -learning_rate*mb/(np.sqrt(vb)+1e-7) # RMSProp-like

提出者Kingma et al. 建议beta1初始值为0.9,beta2初始值为0.999。留意到上面代码多了一些我们没遇到过的,就是correct bias部分,这部分代码我们可以看到它除了(1-(小于1)**t),可以知道,当t很大时,近似于除以1,因此这个代码只在前期的时候有作用,一个解释就是因为m和b初始值是置0的,加入这段代码是为了修正前期m和b。


逃不了的学习率

虽然方法越来越好,但是我们始终可以看到,learning_rate一直形影不离地跟着我们,因此,这些方法是否管用,首先是learning rate一定要合适。相信各位读者有一定的机器学习的方法的积累,这时我们自然而然地就能想到validation(或cross-validation)用来选择学习率,通常初始学习率设为0.01都会有个比较好的表现。我们希望在初期学习率大一些,权重更新的程度大些,而到了收敛阶段学习率小些,权重更新得谨慎一些。因此一般让学习率虽然迭代次数的增加而逐渐变小。
一般有这三种策略:


  • step decay
    乘于decay_rate(一般设0.9或0.99)每过一定数量的迭代(在VGG中,当validation error不减时就进行decay)
  • exponential decay


    λ=λekt
  • 1/t decay


    λ=λ/(1+kt)

如果上面的方法最终得到的权重时INF或者NAN,那么就需要考虑使用更小的初始学习率了(一般学习率都是从大往小找的)。


正则化方法:Dropout

顾名思义,Dropout方法就是在训练的过程中将使用Dropout的层中一定比例的神经元输出置零。



注意:这里我们只在训练的时候使用Dropout,在测试阶段我们需要把Dropout屏蔽


课程上给出了Dropout之所以具有正则化能力的两个解释:


  • 强迫网络拥有冗余的表示
  • Dropout在训练一个大规模的网络组合(ensemble)


强迫网络拥有冗余的表示:因为在每轮迭代中,总是随机屏蔽一定比例的神经元,因此输出并不知道它正在组合哪些特征,因此,比起之前能够专注于某些个特征(比如对识别猫来说,可能有长长的尾巴会是模型专注的一个特征),现在模型不敢这么肯定了,因此它开始把专注力分散到每个特征,使得这些特征也能具备比较好的预测能力。因为将专注力分散了,那么原本具有很高权重的那些特征现在的权重就会被压缩,从而达到了正则化的功能。

Dropout在训练一个大规模的网络组合:在每轮迭代的时候,都是随机生成一个二值的mask用来屏蔽一部分神经元。因此我们可以这样认为,相比之前使用所有的数据在一个模型里面训练,Dropout相当于是为每一个数据都提供一个小模型,然后再将这些模型组合起来的一种方法。(然而小编也没有理解为什么组合小模型就能减轻overfit了,有没可能是跟Boosting这些方法有共同之处?但是考虑到像Adaboost这些都是用一堆high bias的模型组合,这里我们可以说Dropout的小模型对单个数据来说是high bias的吗?小编觉得不行= =…读者如果有什么见解或者是认为小编get错point了,希望能够提出,共同学习,谢谢~)

模型复杂程度:一般来说,模型越复杂,overfit的可能性越大,在神经网络中,神经元越多模型越复杂(好像在说废话= =),这时网络由于节点多,可以容量也就大(这里可以认为是网络的记性就强),那么模型就更有overfit这些数据的可能性也就大,所以通过Dropout减少模型复杂度在这个角度上看的确是有正则化的能力的。



下面给出Dropout的Python代码:



注意:由于Dropout在训练的时候是用了一部分的神经元去做训练,在在测试阶段由于我们是用整个网络去训练,因此我们需要注意在训练的时候为每个存活下来的神经元做同采样比例的放大(除以p),注意,这只在训练时候做,用以保证训练得到的权重在组合之后不会太大;另外一种选择就是把测试结果根据采样比例缩小(乘于p)。


def dropout_forward(x, dropout_param):
"""
Performs the forward pass for (inverted) dropout.
Inputs:
- x: Input data, of any shape
- dropout_param: A dictionary with the following keys:
- p: Dropout parameter. We drop each neuron output with probability p.
- mode: 'test' or 'train'. If the mode is train, then perform dropout;
if the mode is test, then just return the input.
- seed: Seed for the random number generator. Passing seed makes this
function deterministic, which is needed for gradient checking but not in
real networks.
Outputs:
- out: Array of the same shape as x.
- cache: A tuple (dropout_param, mask). In training mode, mask is the dropout
mask that was used to multiply the input; in test mode, mask is None.
"""

p, mode = dropout_param['p'], dropout_param['mode']
if 'seed' in dropout_param:
np.random.seed(dropout_param['seed'])
mask = None
out = None
if mode == 'train':
mask = (np.random.rand(*x.shape) out = x*mask
pass
elif mode == 'test':
out = x*(np.random.rand(*x.shape) pass
cache = (dropout_param, mask)
out = out.astype(x.dtype, copy=False)
return out, cache
def dropout_backward(dout, cache):
"""
Perform the backward pass for (inverted) dropout.
Inputs:
- dout: Upstream derivatives, of any shape
- cache: (dropout_param, mask) from dropout_forward.
"""

dropout_param, mask = cache
mode = dropout_param['mode']
dx = None
if mode == 'train':
dx = dout * mask
pass
elif mode == 'test':
dx = dout
return dx

后言

到了这里,可以说我们已经基本覆盖掉了深度学习里面常见方法,那么用这些方法,我们就可以自信地踏入深度学习这片神奇的领域了。在之后的章节,我将跟大家介绍深度学习的各种层,相信过不了多久就可以开始构建属于自己的深度神经网络了:),一颗赛艇。小编最近更新blog会减慢些,因为最近的课程快end了,期末项目有点多= =…希望下一周能够尽量把CS231n的精华贡献给大家之后如果有可能会开始介绍Caffe的安装以及使用等等…敬请期待:)。


推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
author-avatar
天之蓝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有